package controller

import (
	"bookManage/dao/mysql"
	"bookManage/model"
	"strconv"

	"github.com/gin-gonic/gin"
)

/**
 * @author hujianli
 */

// 无论是在获取书籍列表还是获取特定书籍详情时，都将返回一个新的结构体 BookResponse，
// 其中用户的密码和 Token 字段已被排除。这样就可以保证在视图中不返回用户表的密码和 Token 信息。
type BookResponse struct {
	ID        uint     `json:"id"`
	Name      string   `json:"name"`
	Desc      string   `json:"desc"`
	UserIDs   []uint   `json:"user_ids"`
	Usernames []string `json:"usernames"`
}

// 增
func CreateBookHandler(c *gin.Context) {
	p := new(model.Book)
	if err := c.ShouldBindJSON(p); err != nil {
		c.JSON(400, gin.H{"err": err.Error()})
		return
	}
	mysql.DB.Create(p)
	c.JSON(200, gin.H{"msg": "success"})
}

// 查看书籍列表
func GetBookListHandler(c *gin.Context) {
	books := []model.Book{}
	mysql.DB.Preload("Users").Find(&books)
	// //mysql.DB.Find(&books)//只查书籍，不查关联User
	// c.JSON(200, gin.H{"books": books})
	// 构建响应对象
	bookResponses := []BookResponse{}
	for _, book := range books {
		userIDs := []uint{}
		usernames := []string{}
		for _, user := range book.Users {
			userIDs = append(userIDs, user.Id)
			usernames = append(usernames, user.Username)
		}

		bookResponse := BookResponse{
			ID:        book.Id,
			Name:      book.Name,
			Desc:      book.Desc,
			UserIDs:   userIDs,
			Usernames: usernames,
		}
		bookResponses = append(bookResponses, bookResponse)
	}

	c.JSON(200, gin.H{"books": bookResponses})
}

// 查看指定书籍
func GetBookDetailHandler(c *gin.Context) {
	pipelineIdStr := c.Param("id") //获取URL参数
	bookId, _ := strconv.ParseUint(pipelineIdStr, 10, 64)
	book := model.Book{Id: uint(bookId)}
	mysql.DB.Preload("Users").Find(&book)
	// mysql.DB.Find(&book) //只查书籍，不查关联User
	userIDs := []uint{}
	usernames := []string{}
	for _, user := range book.Users {
		userIDs = append(userIDs, user.Id)
		usernames = append(usernames, user.Username)
	}

	bookResponse := BookResponse{
		ID:        book.Id,
		Name:      book.Name,
		Desc:      book.Desc,
		UserIDs:   userIDs,
		Usernames: usernames,
	}

	c.JSON(200, gin.H{"book": bookResponse})
	// c.JSON(200, gin.H{"books": book})
}

// 改
func UpdateBookHandler(c *gin.Context) {
	p := new(model.Book)
	if err := c.ShouldBindJSON(p); err != nil {
		c.JSON(400, gin.H{"err": err.Error()})
		return
	}
	oldBook := &model.Book{Id: p.Id}
	var newBook model.Book
	if p.Name != "" {
		newBook.Name = p.Name
	}
	if p.Desc != "" {
		newBook.Desc = p.Desc
	}
	mysql.DB.Model(&oldBook).Updates(newBook)
	c.JSON(200, gin.H{"book": newBook})
}

// 删除
func DeleteBookHandler(c *gin.Context) {
	pipelineIdStr := c.Param("id") //获取URL参数
	//字符串，进制，64表示int64
	bookId, _ := strconv.ParseUint(pipelineIdStr, 10, 64)
	//删除book时，也删除四三张表中的用户对应关系记录
	mysql.DB.Select("Users").Delete(&model.Book{Id: uint(bookId)})
	c.JSON(200, gin.H{"msg": "success"})
}

// 增加一条借阅记录
func CreateBookUsersHandler(c *gin.Context) {
	u := new(model.BookUser)
	if err := c.ShouldBindJSON(u); err != nil {
		c.JSON(400, gin.H{"err": err.Error()})
		return
	}
	mysql.DB.Create(u)
	c.JSON(200, gin.H{"msg": "success"})
}

// 查看书籍的借阅记录
func GetBookrecordsHandler(c *gin.Context) {
	book := new(model.Book)
	if err := c.ShouldBindJSON(book); err != nil {
		c.JSON(400, gin.H{"err": err.Error()})
		return
	}
	mysql.DB.Preload("Users").Find(&book)
	usernames := []string{}
	for i := 0; i < len(book.Users); i++ {
		usernames = append(usernames, strconv.FormatInt(int64(book.Users[i].Id), 10))
		usernames = append(usernames, book.Users[i].Username)
	}
	c.JSON(200, usernames)
}
